package com.swiot.biz.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.swiot.biz.constants.TemplateConstants;
import com.swiot.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Luckysheet数据解析工具类
 *
 * @author system
 */
@Component
public class LuckysheetDataParser {

    private static final Logger log = LoggerFactory.getLogger(LuckysheetDataParser.class);

    /**
     * 从Luckysheet数据中提取指定行列位置的数据
     *
     * @param templateContent Luckysheet模板内容
     * @param rowCol          行列位置，格式为"行:列"
     * @return 提取的数据
     */
    public String extractDataFromLuckysheet(String templateContent, String rowCol) {
        try {
            log.info("开始解析luckysheet数据，行列位置：{}", rowCol);

            int[] rowColArray = parseRowCol(rowCol);
            JSONArray sheetData = getSheetData(templateContent);

            return extractCellData(sheetData, rowColArray[0], rowColArray[1]);

        } catch (Exception e) {
            log.error("解析luckysheet数据时发生错误：", e);
            throw new ServiceException(TemplateConstants.ErrorMessages.PARSE_TEMPLATE_FAILED + "：" + e.getMessage());
        }
    }

    /**
     * 从Luckysheet数据中提取字段列表
     *
     * @param templateContent Luckysheet模板内容
     * @param fieldRowCol     字段行列位置，格式为"行:列"
     * @return 字段列表
     */
    public List<String> extractFieldsFromLuckysheet(String templateContent, String fieldRowCol) {
        try {
            log.info("开始提取字段信息，字段行列位置：{}", fieldRowCol);

            int[] rowColArray = parseRowCol(fieldRowCol);
            JSONArray sheetData = getSheetData(templateContent);

            return extractFieldList(sheetData, rowColArray[0], rowColArray[1]);

        } catch (Exception e) {
            log.error("提取字段信息时发生错误：", e);
            throw new ServiceException(TemplateConstants.ErrorMessages.PARSE_TEMPLATE_FAILED + "：" + e.getMessage());
        }
    }

    /**
     * 从Luckysheet数据中提取字段列表
     *
     * @param templateContent Luckysheet模板内容
     * @param row             字段行位置
     * @param fieldCol        字段列位置
     * @param valueCol        值列位置
     * @param alarmCol        报警列位置
     * @return 字段列表
     */
    public JSONObject extractFieldsObjectsFromLuckysheet(String templateContent, int row, int fieldCol, int valueCol, int alarmCol) {
        return extractFieldsObjectsFromLuckysheet(templateContent, row, fieldCol, valueCol, alarmCol,null);
    }



        /**
         * 从Luckysheet数据中提取字段列表
         *
         * @param templateContent Luckysheet模板内容
         * @param row             字段行位置
         * @param fieldCol        字段列位置
         * @param valueCol        值列位置
         * @param alarmCol        报警列位置
         * @return 字段列表
         */
    public JSONObject extractFieldsObjectsFromLuckysheet(String templateContent, int row, int fieldCol, int valueCol, int alarmCol,JSONObject fieldObject) {
        try {
            log.info("开始提取字段信息，字段行位置：{}", row);

            JSONArray sheetData = getSheetData(templateContent);
            validateRowPosition(sheetData, row);

            return extractFieldObjects(sheetData, row, fieldCol, valueCol, alarmCol,fieldObject);

        } catch (Exception e) {
            log.error("提取字段信息时发生错误：", e);
            throw new ServiceException(TemplateConstants.ErrorMessages.PARSE_TEMPLATE_FAILED + "：" + e.getMessage());
        }
    }

    /**
     * 转换为视图格式
     *
     * @param templateContent Luckysheet模板内容
     * @param colIndexes     要删除的列索引
     * @return 转换后的JSON字符串
     */
    public String convertToView(String templateContent, int... colIndexes) {
        try {
            JSONObject jsonData = JSON.parseObject(templateContent);
            if (jsonData == null) {
                throw new ServiceException(TemplateConstants.ErrorMessages.JSON_PARSE_ERROR);
            }

            // 对colIndexes按从大到小排序
            int[] sortedColIndexes = Arrays.stream(colIndexes)
                    .boxed()
                    .sorted(Collections.reverseOrder())
                    .mapToInt(Integer::intValue)
                    .toArray();

            JSONArray data = jsonData.getJSONArray("data").getJSONObject(0).getJSONArray("data");
            for (int i = 0; i < data.size(); i++) {
                JSONArray rowData = data.getJSONArray(i);
                for (int sortedColIndex : sortedColIndexes) {
                    if (sortedColIndex < rowData.size()) {
                        rowData.remove(sortedColIndex);
                    }
                }
            }

            log.debug("转换后的jsonData: {}", jsonData);
            return jsonData.toJSONString();

        } catch (Exception e) {
            log.error("转换视图格式时发生错误：", e);
            throw new ServiceException("转换视图格式失败：" + e.getMessage());
        }
    }

    // ====================== 私有辅助方法 ======================

    /**
     * 解析行列位置字符串
     */
    private int[] parseRowCol(String rowCol) {
        String[] parts = rowCol.split(TemplateConstants.ROW_COL_SEPARATOR);
        if (parts.length != 2) {
            log.error("行列格式错误：{}", rowCol);
            throw new ServiceException(TemplateConstants.ErrorMessages.ROW_COL_FORMAT_ERROR);
        }

        try {
            int row = Integer.parseInt(parts[0]);
            int col = Integer.parseInt(parts[1]);
            log.info("解析行列位置：行={}, 列={}", row, col);
            return new int[]{row, col};
        } catch (NumberFormatException e) {
            log.error("行列位置格式错误，必须为数字：{}", rowCol);
            throw new ServiceException(TemplateConstants.ErrorMessages.ROW_COL_FORMAT_ERROR);
        }
    }

    /**
     * 获取工作表数据
     */
    private JSONArray getSheetData(String templateContent) {
        JSONObject jsonData = JSON.parseObject(templateContent);
        if (jsonData == null) {
            log.error("模板内容不是有效的JSON格式");
            throw new ServiceException(TemplateConstants.ErrorMessages.JSON_PARSE_ERROR);
        }

        JSONArray dataArray = jsonData.getJSONArray("data");
        if (dataArray == null || dataArray.isEmpty()) {
            log.error("未找到data数组");
            throw new ServiceException(TemplateConstants.ErrorMessages.CELLDATA_NOT_FOUND);
        }

        JSONObject firstSheet = dataArray.getJSONObject(0);
        if (firstSheet == null) {
            log.error("未找到第一个工作表数据");
            throw new ServiceException(TemplateConstants.ErrorMessages.CELLDATA_NOT_FOUND);
        }

        JSONArray sheetData = firstSheet.getJSONArray("data");
        if (sheetData == null || sheetData.isEmpty()) {
            log.error("未找到工作表数据数组");
            throw new ServiceException(TemplateConstants.ErrorMessages.CELLDATA_NOT_FOUND);
        }

        log.info("找到工作表数据数组，长度：{}", sheetData.size());
        return sheetData;
    }

    /**
     * 验证行位置是否有效
     */
    private void validateRowPosition(JSONArray sheetData, int row) {
        int actualRow = row + 1;
        if (actualRow >= sheetData.size()) {
            log.error("行索引超出范围：{} >= {}", actualRow, sheetData.size());
            throw new ServiceException(TemplateConstants.ErrorMessages.POSITION_NOT_FOUND);
        }
    }

    /**
     * 提取单元格数据
     */
    private String extractCellData(JSONArray sheetData, int row, int col) {
        validateRowPosition(sheetData, row);

        int actualRow = row + 1;
        JSONArray rowData = sheetData.getJSONArray(actualRow);
        if (rowData == null) {
            log.error("未找到第{}行数据", actualRow);
            throw new ServiceException(TemplateConstants.ErrorMessages.POSITION_NOT_FOUND);
        }

        if (col >= rowData.size()) {
            log.error("列索引超出范围：{} >= {}", col, rowData.size());
            throw new ServiceException(TemplateConstants.ErrorMessages.POSITION_NOT_FOUND);
        }

        Object cellObject = rowData.get(col);
        String result = extractCellValue(cellObject);

        log.info("找到指定行列的数据：{}", result);
        return result;
    }

    /**
     * 提取字段列表
     */
    private List<String> extractFieldList(JSONArray sheetData, int row, int col) {
        validateRowPosition(sheetData, row);

        int actualRow = row + 1;
        List<String> fieldList = new ArrayList<>();

        for (int currRow = actualRow; currRow < sheetData.size(); currRow++) {
            JSONArray rowData = sheetData.getJSONArray(currRow);
            if (rowData == null) {
                log.error("未找到第{}行数据", currRow);
                continue;
            }

            JSONObject cellObject = rowData.getJSONObject(col);
            String fieldValue = extractCellValue(cellObject);

            if (fieldValue != null && !fieldValue.trim().isEmpty()) {
                fieldList.add(fieldValue.trim());
            }
        }

        log.info("提取到{}个字段：{}", fieldList.size(), fieldList);
        return fieldList;
    }

    private JSONObject extractFieldObjects(JSONArray sheetData, int row, int fieldCol, int valueCol, int alarmCol) {
        return extractFieldObjects(sheetData, row, fieldCol, valueCol, alarmCol, null);
    }

    /**
     * 提取字段对象
     */
    private JSONObject extractFieldObjects(JSONArray sheetData, int row, int fieldCol, int valueCol, int alarmCol,JSONObject fieldObject) {
        int actualRow = row + 1;
        JSONObject fieldList = new JSONObject();
        if (fieldObject != null) {
            fieldList = fieldObject;
        }
        for (int currRow = actualRow; currRow < sheetData.size(); currRow++) {
            JSONArray rowData = sheetData.getJSONArray(currRow);
            if (rowData == null) {
                log.error("未找到第{}行数据", currRow);
                continue;
            }

            String fieldCell = extractCellValue(rowData.getJSONObject(fieldCol));
            if (fieldCell == null || fieldCell.trim().isEmpty()) {
                break;
            }

            JSONObject values = new JSONObject();
            values.put("value", extractCellValue(rowData.getJSONObject(valueCol)));
            values.put("alarm", extractCellValue(rowData.getJSONObject(alarmCol)));
            if (fieldObject != null) {
                if(fieldObject.containsKey(fieldCell.trim())){
                    fieldObject.put(fieldCell.trim(), values);
                }
            }else {
                fieldList.put(fieldCell.trim(), values);
            }

        }

        return fieldList;
    }

    /**
     * 提取单元格的值
     *
     * @param cellObject 单元格对象
     * @return 单元格的值
     */
    private String extractCellValue(Object cellObject) {
        if (cellObject == null) {
            return null;
        }

        if (cellObject instanceof JSONObject) {
            JSONObject cellJson = (JSONObject) cellObject;
            Object vValue = cellJson.get("v");
            return vValue != null ? vValue.toString() : "";
        } else {
            return cellObject.toString();
        }
    }
}
